package com.mornd.gulimall.order;

import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 *
 * 分布式事务 seata 使用：
 * 1、每个服务创建 undo_log 表, 创建seata管理库
 * 2、安装事务协调器tc：https://github.com/seata/seata/releases  https://github.com/seata/seata/releases/download/v1.6.1/seata-server-1.6.1.tar.gz
 * 4、导入依赖
 *      spring-cloud-starter-alibaba-seata
 * 5、seata-all 1.6.1 (修改配置文件启动)
 * 6、让 seata 代理数据源
 * 7、配置seata和项目的yaml nacos添加seata配置
 * 8、入口方法标注事务注解
 * 8、启动
 *
 *
 * seata的四种模式:
 * XA: 强一致性分阶段事务模式，牺牲了一定的可用性，无业务侵入,通过数据库的事务实现，tc检测各个rm的状态，如果都成功，即都提交个rm的事务，有一个rm失败，则全都回滚
 * AT: seata默认模式,最终一致的分阶段事务模式，无业务侵入,事务开始前,seata通过每个服务下的undo-log表记录当前状态,事务结束后再记录一次,通过undo-log日志来进行回滚,通过全局锁来保证并发安全
 * TCC: 最终一致的分阶段事务模式，有业务侵入,手动编写try，confirm，cancel接口,可以运用于非事务数据库
 * SAGA: 长事务模式，有业务侵入
 *
 *
 *
 * mysql问题：
 * 同一个ip在短时间内产生太多（超过mysql数据库max_connection_errors的最大值）中断的数据库连接而导致的阻塞；当客户端连接服务端超时(超过connect_timeout，默认10s), 服务端就会给这个客户端记录一次error，当出错的次数达到max_connect_errors的时候，这个客户端就会被锁定。
 * 并提示报错信息：java.sql.SQLException: null,  message from server: "Host '127.0.0.1' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'"
 * max_connect_errors默认值为100，可通过  SHOW GLOBAL VARIABLES LIKE '%max_connect_errors%'; 查看
 * 通过 set global max_connect_errors=1000; 进行修改
 *
 */

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.mornd.gulimall.apis")
//@ComponentScan("com.mornd.gulimall.apis.coupon.fallback")
@EnableRabbit
@EnableAspectJAutoProxy(exposeProxy = true)
public class OrderApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(OrderApplication.class, args);
    }

}
